package com.issue.common.utils.excel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 针对大数据可持续导出数据工具类
 *
 * @author 56392
 */
@Data
@Slf4j
public class EasyExcelBigDataExport {



    /** 导出 Excel 转换的数据类型 **/
    private Class exportClass;

    /** 导出的 Excel 文件名称 **/
    private String fileName;

    /** 表头行数 **/
    private int headRow = 0;

    /** 额外的样式 **/
    private WriteHandler otherWriteHandler;

    /** 返回流 **/
    private HttpServletResponse response;

    /** 输出流 **/
    private ExcelWriter excelWriter;

    private int sheetNo = 0;

    private EasyExcelBigDataExport() {

    }

    public static class Builder{

        private EasyExcelBigDataExport easyExcelExport;

        public Builder(){
            easyExcelExport = new EasyExcelBigDataExport();
        }

        public Builder setExportClass(Class exportClass){
            easyExcelExport.setExportClass(exportClass);
            return this;
        }

        public Builder setFileName(String fileName){
            easyExcelExport.setFileName(fileName);
            return this;
        }

        public Builder setHeadHeight(int headRow){
            easyExcelExport.setHeadRow(headRow);
            return this;
        }

        public Builder setOtherWriteHandler(WriteHandler otherWriteHandler){
            easyExcelExport.setOtherWriteHandler(otherWriteHandler);
            return this;
        }

        public Builder setResponse(HttpServletResponse response){
            easyExcelExport.setResponse(response);
            return this;
        }

        public EasyExcelBigDataExport create() throws Exception {
            // 产生头部和内容样式
            HorizontalCellStyleStrategy headWriteHandler = EasyExcelUtil.generateHeadWriter();
            // 初始化报文
            EasyExcelUtil.initResponse(easyExcelExport.response, easyExcelExport.otherWriteHandler, easyExcelExport.fileName);
            // 初始化 ExcelWriter
            ExcelWriter excelWriter = EasyExcelUtil.generateExcelWriter(easyExcelExport.response, easyExcelExport.otherWriteHandler,
                    headWriteHandler);
            easyExcelExport.setExcelWriter(excelWriter);
            return easyExcelExport;
        }

    }

    /**
     * 支持单数据源 Excel 导出
     *
     * @param pageList    需要导出Excel的数据，不得超过 100 万行
     * @throws Exception /
     */
    public <T> void exportExcel(List<T> pageList) throws Exception {

        // 不能超过行数限制
        if (CollectionUtils.isEmpty(pageList) || pageList.size() > Constants.Excel.SINGLE_SHEET_COUNT){
            return;
        }
        // 超出最大 sheet 限制
        if (sheetNo >= Constants.Excel.MAX_SHEET_COUNT){
            log.error("Excel 超出最大 Sheet 限制数！");
            return;
        }

        EasyExcelUtil.SheetExport sheetExport = new EasyExcelUtil.SheetExport<T>();
        sheetExport.exportClass = exportClass;
        sheetExport.headRow = headRow;
        sheetExport.data = pageList;
        sheetExport.name = fileName + sheetNo;

        WriteSheet writeSheet = EasyExcel.writerSheet(sheetNo, sheetExport.name)
                .head(sheetExport.exportClass)
                .relativeHeadRowIndex(sheetExport.headRow)
                .build();

        excelWriter.write(sheetExport.data, writeSheet);

        sheetNo++;
    }

    /**
     * 结束输出
     *
     */
    public <T> void finish() throws Exception{
        if (excelWriter != null){
            excelWriter.finish();
        }
    }



}
